package com.ebelter.scaleblesdk.util;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;


import com.ebelter.scaleblesdk.model.FileType;
import com.ebelter.scaleblesdk.util.ULog;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * assets资源加载器，可国际化
 * Created by pan on 2017/6/22.
 */
public class AssetsLoader {
    public static final String TAG = "AssetsLoader";

    private final static String FIRMWARE_PATH = "firmware";

    private static List<byte[]> blePackages = new ArrayList<>();
    private static List<byte[]> scalePackages = new ArrayList<>();
    //异或校验结果值
    private static byte blexorByte = 0;
    private static byte scalexorByte = 0;
    private static byte bleCheckCrc8 = 0;
    private static byte scaleCheckCrc8 = 0;

    /**
     * 获取匹配文件的文件名
     *
     * @param ctx
     * @param match
     * @return
     */
    public static String getFirmwareMatchFileName(Context ctx, String match) {

        String matchFileName = null;
        AssetManager am = ctx.getAssets();
        try {
            String[] fileNames = am.list(FIRMWARE_PATH);
            for (String filename : fileNames) {
                ULog.i(TAG, "------getMatchFile------filename = " + filename);
                if (filename.startsWith(match)) {
                    matchFileName = filename;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return matchFileName;
    }

    /**
     * 获取文件字节数组
     *
     * @param ctx
     * @param fileName
     * @return
     */
    public static byte[] getFileByteArray(Context ctx, String fileName) {
        AssetManager am = ctx.getAssets();
        byte[] buffer = null;
        InputStream is = null;
        try {
            is = am.open(FIRMWARE_PATH + "/" + fileName);
            int len = is.available();
            buffer = new byte[len];
            is.read(buffer);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return buffer;
    }

    /**
     * 获取文件字节长度
     *
     * @param ctx
     * @param fileName
     * @return
     */
    public static long getFileLength(Context ctx, String fileName) {
        long len = 0;
        AssetManager am = ctx.getAssets();
        InputStream is = null;
        try {
            is = am.open(FIRMWARE_PATH + "/" + fileName);
            len = is.available();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return len;
    }


    /**
     * 加载Assets下的固件文件到内存
     *
     * @param ctx
     * @param fileType
     * @param fileName
     */
    public static void loadAssetsFirmwareFile(Context ctx, FileType fileType, String fileName) {
        byte xorByte = 0;
        byte otaCheckCrc8 = 0;
        List<byte[]> packages = null;
        switch (fileType) {
            case BLE_FIRMWARE:
                packages = blePackages;
                break;
            case SCALE_FIRMWARE:
                packages = scalePackages;
                break;
        }
        ULog.i(TAG, "------loadAssetsFirmwareFile------fileType = " + fileType);
        AssetManager am = ctx.getAssets();
        InputStream is = null;
        try {
            is = am.open(FIRMWARE_PATH + "/" + fileName);
            byte[] tempBytes = new byte[16];
            int readByte;
            while ((readByte = is.read(tempBytes)) != -1) {
                byte[] bs = tempBytes.clone();
                //每一包接收之后都进行处理
                xorByte = getXor(bs, xorByte);
                otaCheckCrc8 = getCrc8Check(bs, otaCheckCrc8);
                ULog.i(TAG, "------loadAssetsFirmwareFile------otaCheckCrc8 = " + otaCheckCrc8);
                if (packages != null) {
                    packages.add(bs);
                }

                switch (fileType) {
                    case BLE_FIRMWARE:
                        bleCheckCrc8 = otaCheckCrc8;
                        blexorByte = xorByte;
                        break;
                    case SCALE_FIRMWARE:
                        scaleCheckCrc8 = otaCheckCrc8;
                        scalexorByte = xorByte;
                        break;
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取下发数据包异或校验结果值
     *
     * @param bytes
     * @param xorByte
     * @return
     */
    private static byte getXor(byte[] bytes, byte xorByte) {
        int bsLen = bytes.length;
        for (int i = 0, j = 0; i < 16; i++, j++) {
            if (j >= bsLen) {
                xorByte ^= 0xff;
            } else {
                xorByte ^= bytes[j];
            }
        }
        return xorByte;
    }

    /**
     * CRC8校验
     *
     * @param bytes
     * @param result
     * @return
     */
    private static byte getCrc8Check(byte[] bytes, byte result) {
        //otaCheckCrc8_1
        int size = bytes.length;

        for (int i = 0; i < size; i++) {
            result ^= bytes[i];
            for (int j = 0; j < 8; j++) {
                if ((result & 0x80) > 0) {
                    result <<= 1;
                    result = (byte) (result ^ 7);
                } else {
                    result <<= 1;
                }
            }
        }
        return result;
    }


    /**
     * 获取固件检验值
     *
     * @param fileType
     * @return
     */
    public static byte getFirmwareCrc8Check(FileType fileType) {
        byte cs = -1;
        switch (fileType) {
            case BLE_FIRMWARE:
                cs = bleCheckCrc8;
                break;
            case SCALE_FIRMWARE:
                cs = scaleCheckCrc8;
                break;

        }
        return cs;
    }


    /**
     * 获取固件分包总个数
     *
     * @param fileType
     * @return
     */
    public static int getFirmwarePackageLength(FileType fileType) {
        int len = 0;
        switch (fileType) {
            case BLE_FIRMWARE:
                len = blePackages.size();
                break;
            case SCALE_FIRMWARE:
                len = scalePackages.size();
                break;

        }
        return len;
    }

    /**
     * 获取固件分包列表
     *
     * @param fileType
     * @return
     */
    public static List<byte[]> getFirmwarePackagesByte(FileType fileType) {
        List<byte[]> packages = null;
        switch (fileType) {
            case BLE_FIRMWARE:
                packages = blePackages;
                break;
            case SCALE_FIRMWARE:
                packages = scalePackages;
                break;

        }
        return packages;
    }


}
